<?php

namespace tools\lib\main\model;

use tools\lib\main\Common;

class Validate extends Common
{
    private $rules = '[]';

    private $message = '[]';

    public function template()
    {
        $this->getRule();

        $template = <<<EOT
<?php

{$this->getFileNamespace()}

{$this->getFileUse()}

class {$this->className()} {$this->getFileExtends()}
{
    protected \$rule = $this->rules;

    protected \$message = $this->message;
}
EOT;
        return $template;
    }

    /**
     * @return bool
     */
    private function getRule()
    {
        $columns = tableColumns($this->parameter->getName());

        $rule_template = [];

        $message_template = [];


        if ($columns) {

            foreach ($columns as $column) {

                $rules = [];

                $field = $column['Field'];

                if (in_array($field, [
                    'id',
                    'create_time',
                    'update_time',
                    'delete_time'
                ])) {
                    continue;
                }

                preg_match('/([a-z]+).*?([0-9]+)/', $column['Type'], $matches);

                if ($matches) {
                    $type = isset($matches[1]) ? $matches[1] : '';
                    $length = isset($matches[2]) ? $matches[2] : '';
                } else {
                    $type = $column['Type'];
                    $length = 0;
                }

                // 必填
                if ($column['Null'] !== 'YES' && $column['Default'] === null) {
                    $rules[] = 'require';
                }

                // email
                if ($field == 'email') {
                    $rules[] = 'email';
                }

                switch ($type) {
                    case 'tinyint':
                        $rules[] = 'integer';
                        $field_comment = parseFieldComment($column);
                        if ($field_comment) {
                            $number = 'in:';
                            foreach ($field_comment as $comment) {
                                $number .= $comment[0] . ',';
                            }
                            $rules[] = trim($number, ',');
                        } else {
                            $rules[] = 'between:1,127';
                        }
                        break;
                    case 'smallint':
                    case 'int':
                    case 'integer':
                        $rules[] = 'integer';
                        break;
                    case 'decimal':
                        $rules[] = 'float';
                        break;
                    case 'datetime':
                        $rules[] = 'dateFormat:Y-m-d H:i:s';
                        break;
                    case 'date':
                        $rules[] = 'dateFormat:Y-m-d';
                        break;
                    case 'time':
                        $rules[] = 'dateFormat:H:i:s';
                        break;
                    default:
                        if ($length) {
                            $rules[] = 'length:1,' . $length;
                        }
                }

                /**
                 * 特殊处理
                 */
                if ($field === 'phone') {
                    $rules = [
                        'require',
                        'number',
                        'unique:' . $this->parameter->getName(),
                        'length:11'
                    ];
                } elseif (in_array($field, ['start_time', 'end_time'])) {
                    $rules = [
                        'require',
                        'date'
                    ];
                } elseif ($field === 'url') {
                    $rules = [
                        'require',
                        'url'
                    ];
                } elseif ($field === 'password') {
                    $rules = [
                        'password' => [
                            'require',
                            'alphaDash',
                            'length:6,18'
                        ],
                        'confirm' => [
                            'require',
                            'confirm:password'
                        ]
                    ];
                }

                $parse_rule = function ($item) use ($column, $length) {
                    $separator = strpos($item, ':');

                    if ($separator) {
                        $rule = substr($item, 0, $separator);
                        $value = substr($item, $separator + 1);
                    } else {
                        $rule = $item;
                        $value = 0;
                    }

                    $comment = $column['Comment'];

                    if ($comment) {
                        $comment = explode(' ', $comment);
                    } else {
                        $comment = [];
                    }

                    $message = isset($comment[0]) ? $comment[0] : '';
                    if ($rule == 'require') {
                        $message = '请输入' . $message;
                    } elseif ($rule == 'length') {
                        $message = $message . '长度不正确,允许的长度1~' . $length;
                    } elseif ($rule == 'between') {
                        $message = $message . '取值范围在 ' . str_replace(',', '~', $value);
                    } elseif ($rule == 'in') {
                        $message = $message . '可选值错误';
                    } elseif ($rule == 'alphaDash') {
                        $message = $message . '值为字母、数字、下划线的组合';
                    } elseif ($rule == 'unique') {
                        $message = $message . '已经被使用';
                    } elseif ($rule == 'confirm') {
                        $message = $message . '密码跟确认密码不一致';
                    } else {
                        $message = $message . '格式错误';
                    }

                    return ['rule' => $rule, 'message' => $message];
                };

                $messages = [];
                if ($rules) {
                    foreach ($rules as $key => $rule) {
                        if (is_array($rule)) {
                            foreach ($rule as $item) {
                                $item = $parse_rule($item);
                                $messages[$key . '.' . $item['rule']] = $item['message'];
                                $rule_template[$key] = implode('|', $rule);
                            }
                        } else {
                            $rule = $parse_rule($rule);
                            $messages[$field . '.' . $rule['rule']] = $rule['message'];
                            $rule_template[$field] = implode('|', $rules);
                        }
                    }
                }

                foreach ($messages as $key => $message) {
                    $message_template[$key] = $message;
                }

            }
        }

        $this->rules = concatArrayFormat($rule_template);

        $this->message = concatArrayFormat($message_template);

        return true;
    }
}